package com.example.demo.service.Impl;

import com.example.demo.dao.ShiftDao;
import com.example.demo.entity.GeneGroup;
import com.example.demo.entity.Shift;
import com.example.demo.entity.Staff;
import com.example.demo.entity.Store;
import com.example.demo.mapper.ShiftMapper;
import com.example.demo.service.ShiftService;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.sql.Date;
import java.util.List;

/**
 * @Project:demo
 * @Description: 排班服务层
 * @Author: Mr.Hunter
 * @Date:2023/3/25/18:53
 */
@Service
public class ShiftServiceImpl implements ShiftService {

    @Autowired
    private ShiftMapper shiftMapper;
    private final ShiftDao shiftDao;

    public ShiftServiceImpl(ShiftDao shiftDao) {
        this.shiftDao = shiftDao;
    }

    //    public List<Shift> selectShiftAll() {
//        return shiftMapper.selectShiftAll();
//    }


    public List<Shift> testGa() {
        Staff staff1 = new Staff("1", null);
        Staff staff2 = new Staff("2", null);
        Staff staff3 = new Staff("3", null);
        Staff staff4 = new Staff("4", null);
        Staff staff5 = new Staff("5", null);
        Staff staff6 = new Staff("6", null);
        //创建商铺
        Store store = new Store();
        store.addStaff(staff1);
        store.addStaff(staff2);
        store.addStaff(staff3);
        store.addStaff(staff4);
        store.addStaff(staff5);
        store.addStaff(staff6);
        //创建客流模型
        int[] customers1 = new int[]{
                4, 4, 3, 4, 6, 7, 8, 7, 6, 5, 4, 7, 8, 9, 6, 5, 4, 4, 4, 4, 4, 6, 7, 6, 0, 0
        };
        int[] expertNeedStuff = store.generateExpertNeedStuffList(customers1, 1);
        for (int i = 0; i < expertNeedStuff.length; i++) {
            System.out.print(expertNeedStuff[i]);
        }
//        创建基因组
        GeneGroup geneGroup = new GeneGroup(store);
        int fixTime = 0;//适应次数
        //记录当前商铺的员工值班表 记录
        double fix = Integer.MAX_VALUE;
        GeneGroup tmp = new GeneGroup();

        ArrayList<Double> list = new ArrayList<>();
        while (fixTime < 10) {
            geneGroup.fitness(geneGroup, 1, expertNeedStuff);
            fixTime++;
            list.add(geneGroup.getFitnessValue());
            if (geneGroup.getFitnessValue() < fix) {
                tmp = geneGroup;
                fix = geneGroup.getFitnessValue();
            }
            geneGroup = new GeneGroup(store);
        }
        store = tmp.getStore();
        //检索每一个员工的基因
        ArrayList<Shift> shifts = new ArrayList<>();
        for (int i = 0; i < store.staffList.size(); i++) {
            Shift shift = new Shift();//创建员工排班
            shift.setStoreId(1);//设置商铺id
            shift.setStaffId(Integer.valueOf(store.staffList.get(i).getStaffName()));//设置员工id
            StringBuilder stringBuilder = new StringBuilder();
            long millis = System.currentTimeMillis();
            Date date = new Date(millis);
            shift.setWorkDate(date);
            for (int j = 0; j < store.staffList.get(i).gene.chromoSome.get(1).length; j++) {
                stringBuilder.append(store.staffList.get(i).gene.chromoSome.get(1)[j]);//构建字符串
            }
            shift.setShiftScheduling(stringBuilder.toString());
            shifts.add(shift);
        }
        return shifts;
    }

    @Override
    public int save() {
        List<Shift> shifts = testGa();
        for (int i = 0; i < shifts.size(); i++) {
            shiftDao.save(shifts.get(i));
        }
        return shifts.size();
    }


    @Override
    public List<Shift> findByStoreIdAndWorkDate(Integer storeId,
                                                @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") @DateTimeFormat(pattern = "yyyy-MM-dd") Date workDate) {
        return shiftDao.findByStoreIdAndWorkDate(storeId, workDate);
    }

    @Override

    public List<Shift> findByStoreId(Integer storeId) {
        return shiftDao.findByStoreId(storeId);
    }

    @Override
    public List<Shift> findAllByStoreId(Integer storeId) {
        return shiftMapper.selectAllByStoreId(storeId);
    }

    @Override
    public List<Shift> findAllByStoreIdAndWorkDate(Integer storeId, Date workDate) {
        List<Shift> shiftList = shiftMapper.selectByWorkDateAndStoreId(storeId, workDate);
        return shiftList;
    }

    @Override
    public void insertAll(List<Shift> shiftList) {
        shiftMapper.insertAll(shiftList);
    }

    @Override
    public int updateAll(List<Shift> shiftList) {
        return shiftMapper.updateAll(shiftList);
    }

    @Override
    public int updateStaffScheduling(Integer staff_id, Integer store_id, String staff_scheduling, Date work_date) {
        int cnt = shiftMapper.updateStaffScheduling(staff_id, store_id, staff_scheduling, work_date);
        return cnt;
    }

    @Override
    public int updateKeepNowStaffSchedulingByBeginAndEnd(Integer staff_id, Integer store_id, Integer beginTime, Integer endTime, Date work_date) {
        List<Shift> shifts = shiftMapper.selectByWorkDateAndStoreId(store_id, work_date);
        Shift target = new Shift();
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < shifts.size(); i++) {
            if (shifts.get(i).getStaffId() == staff_id) {
                target = shifts.get(i);
            }
        }
        String shiftScheduling = target.getShiftScheduling();
        for (int i = 0; i < 30; i++) {
            if (beginTime <= i && endTime >= i) {
                stringBuilder.append('0');
                continue;
            }
            stringBuilder.append(shiftScheduling.charAt(i));
        }
        shiftScheduling = stringBuilder.toString();
        int cnt = shiftMapper.updateStaffScheduling(staff_id, store_id, shiftScheduling, work_date);
        return cnt;
    }

    @Override
    public int deleteStaffSchedulingByAllZone(Integer staff_id, Integer store_id, Date work_date) {
        int cnt = shiftMapper.updateStaffScheduling(staff_id, store_id, "000000000000000000000000000000", work_date);
        return cnt;
    }

    @Override
    public int updateEmptyStaffSchedulingByBeginAndEnd(Integer staff_id, Integer store_id, Integer beginTime, Integer endTime, Date work_date) {
        List<Shift> shifts = shiftMapper.selectByWorkDateAndStoreId(store_id, work_date);
        Shift target = new Shift();
        for (int i = 0; i < shifts.size(); i++) {
            if (shifts.get(i).getStaffId() == staff_id) {
                target = shifts.get(i);
            }
        }
        String shiftScheduling = target.getShiftScheduling();
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < shiftScheduling.length(); i++) {
            if (i >= beginTime && i <= endTime){
                builder.append('1');
                continue;
            }
            builder.append('0');
        }
        shiftScheduling = builder.toString();
        int cnt = shiftMapper.updateStaffScheduling(staff_id, store_id, shiftScheduling, work_date);
        return cnt;
    }

    @Override
    public int updateRangeStaffSchedulingByBeginAndEnd(Integer staff_id, Integer store_id, Integer beginTime, Integer endTime, Date work_date, Integer origin_start_time, Integer origin_end_time) {
        List<Shift> shifts = shiftMapper.selectByWorkDateAndStoreId(store_id, work_date);
        Shift target = new Shift();
        for (int i = 0; i < shifts.size(); i++) {
            if (shifts.get(i).getStaffId() == staff_id) {
                target = shifts.get(i);
            }
        }
        String shiftScheduling = target.getShiftScheduling();
        StringBuilder builder = new StringBuilder();
        int begin_index = Math.min(beginTime,origin_start_time);
        int end_index = Math.max(endTime,origin_end_time);
        for (int i = 0; i < shiftScheduling.length(); i++) {
            if (shiftScheduling.charAt(i) == '1' && (i < begin_index || i > end_index)){
                builder.append('1');
                continue;
            }
            if (i >= beginTime && i <= endTime){
                builder.append('1');
                continue;
            }
            if (i >= begin_index && i <= beginTime){
                builder.append('0');
                continue;
            }
            if (i < end_index && i > endTime){
                builder.append('0');
                continue;
            }
            builder.append('0');
        }
        shiftScheduling = builder.toString();
        int cnt = shiftMapper.updateStaffScheduling(staff_id, store_id, shiftScheduling, work_date);
        return cnt;
    }

    @Override
    public int updateStaffSchedulingByBeginAndEnd(Integer staff_id, Integer store_id, Integer beginTime, Integer endTime, Date work_date) {
        List<Shift> shifts = shiftMapper.selectByWorkDateAndStoreId(store_id, work_date);
        Shift target = new Shift();
        for (int i = 0; i < shifts.size(); i++) {
            if (shifts.get(i).getStaffId() == staff_id) {
                target = shifts.get(i);
            }
        }
        String shiftScheduling = target.getShiftScheduling();
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < shiftScheduling.length(); i++) {
            if (i >= beginTime && i <= endTime){
                builder.append('1');
                continue;
            }
            builder.append('0');
        }
        shiftScheduling = builder.toString();
        int cnt = shiftMapper.updateStaffScheduling(staff_id, store_id, shiftScheduling, work_date);
        return cnt;
    }

}